<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 
<html>
<head>
<title>ProgressBar widget</title>
<link rel="stylesheet" href="/cfg/format.css" type="text/css">
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="keywords" content="Android, ProgressBar widget, Thread, programming, tutorial, 
Java, mobile development">
<meta name="description" content="In this chapter of the Android tutorial, we present
the ProgressBar widget.">
<meta name="language" content="en">
<meta name="author" content="Jan Bodnar">
<meta name="distribution" content="global">

<script type="text/javascript" src="/lib/jquery.js"></script>
<script type="text/javascript" src="/lib/common.js"></script>

</head>

<body>

<div class="container2">

<div id="wide_ad" class="ltow">
<script type="text/javascript"><!--
google_ad_client = "pub-9706709751191532";
/* 160x600, August 2011 */
google_ad_slot = "2484182563";
google_ad_width = 160;
google_ad_height = 600;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>

<div class="content2">


<a href="/" title="Home">Home</a>&nbsp;
<a href=".." title="Home">Contents</a>


<h1>ProgressBar widget</h1>


<p>
In this chapter of the Android development tutorial we will present the ProgressBar 
widget. A <i>ProgressBar</i> is a widget that shows visually a progress of some task.
The widget comes in two basic modes. There is a circular bar and a horizontal bar.
</p>

<div class="big_hor">
<script type="text/javascript"><!--
google_ad_client = "ca-pub-9706709751191532";
/* big_horizontal */
google_ad_slot = "2904953388";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>

<p>
We will have two examples to demonstrate both of them.
</p>


<h2>ProgressBar I</h2>
 
<p>
We have a horizontal ProgressBar widget and a TextView widget, that
shows the percentage of the task completed. The manifest file is
left untouched.
</p>


<div class="codehead">main.xml</div>
<pre class="code">
&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    &gt;
&lt;ProgressBar 
    android:id="@+id/pbId"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    style="?android:attr/progressBarStyleHorizontal"
    android:layout_margin="10dp"
    /&gt;       
&lt;TextView
    android:id="@+id/tvId"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_margin="10dp"
    /&gt;
&lt;/LinearLayout&gt;
</pre>

<p>
In the <i>main.xml</i> layout file, we have a ProgressBar and a TextView. 
The <code>style="?android:attr/progressBarStyleHorizontal"</code> style
makes the ProgressBar horizontal. The default mode of the ProgressBar
is the circular mode.
</p>

<div class="codehead">strings.xml</div>
<pre class="code">
&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;resources&gt;
    &lt;string name="app_name"&gt;ProgBar&lt;/string&gt;
&lt;/resources&gt;
</pre>

<p>
String resource file.
</p>

<div class="codehead">MainActivity.java</div>
<pre class="code">
package com.zetcode.progbar2;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.util.Log;


public class MainActivity extends Activity
{
    ProgressBar pb;
    TextView tv;
    int prg = 0;

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        pb = (ProgressBar) findViewById(R.id.pbId);
        tv = (TextView) findViewById(R.id.tvId);
 
        new Thread(myThread).start();
    }

    private Runnable myThread = new Runnable()
    { 
        @Override
        public void run() 
        {
            while (prg &lt; 100)
            {
                try
                {
                    hnd.sendMessage(hnd.obtainMessage());
                    Thread.sleep(100);
                }
                catch(InterruptedException e) 
                {  
                    Log.e("ERROR", "Thread was Interrupted");
                }
            }

            runOnUiThread(new Runnable() { 
                public void run() {
                    tv.setText("Finished");
                }
            });          
        }
    
        Handler hnd = new Handler()
        {    
            @Override
            public void handleMessage(Message msg) 
            {
                prg++;
                pb.setProgress(prg);

                String perc = String.valueOf(prg).toString();
                tv.setText(perc+"% completed");
            }
        };
    };
}
</pre>

<p>
We create a thread to control the progress of a ProgressBar.
</p>

<pre class="explanation">
new Thread(myThread).start();
</pre>

<p>
A new thread is started. In Android, lengthy tasks should by performed
inside a thread to prevent the application from appearing unresponsive.
A thread ends by returning from its main() method, or by an exception.
</p>

<pre class="explanation">
@Override
public void run() 
{
    while (prg &lt; 100)
    {
        try
        {
            hnd.sendMessage(hnd.obtainMessage());
            Thread.sleep(100);
        }
        catch(InterruptedException e) 
        {  
            Log.e("ERROR", "Thread was Interrupted");
        }
    }

    runOnUiThread(new Runnable() { 
        public void run() {
            tv.setText("Finished");
        }
    });          
}
</pre>

<p>
The code in a thread is placed in the <code>run()</code> method. We will simulate a
lengthy task by calling the <code>Thread.sleep()</code> method. This forces us to handle
the <i>InterruptedException</i>. Android application runs in a single-thread model. 
All components of the main activity are created in the main thread. These components
cannot be manipulated in other threads. To work around this, we use either the <i>Handler</i>
object or call the <code>runOnUiThread()</code> method.
</p>


<pre class="explanation">
runOnUiThread(new Runnable() { 
    public void run() {
        tv.setText("Finished");
    }
});   
</pre>

<p>
Only the original thread that created a view hierarchy can touch its views.
Here we are modifying the TextView widget. Therefore we have put the code
into the <code>runOnUiThread()</code> method, which runs the code in the
main, UI thread, where the widget was created.
</p>

<pre class="explanation">
Handler hnd = new Handler()
{    
    @Override
    public void handleMessage(Message msg) 
    {
        prg++;
        pb.setProgress(prg);

        String perc = String.valueOf(prg).toString();
        tv.setText(perc+"% completed");
    }
};
</pre>

<p>
Another way to touch widgets from another thread is to use the <i>Handler</i> object.
It is used to enqueue an action to be performed on a different thread than its own.
We update the progress bar and set a percentage of the task completed to the 
text view.
</p>

<img src="/img/java/android/progbar1.png" alt="ProgressBar widget">
<div class="figure">
Figure: ProgressBar widget
</div>


<h2>ProgressBar II</h2>
 
<p>
In the second example, we show the usage of the ProgressBar in a circular
mode. The manifest file does not need to be modified.
</p>

<div class="codehead">main.xml</div>
<pre class="code">
&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    &gt;
&lt;ProgressBar 
    android:id="@+id/pbId"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    /&gt;    
&lt;TextView
    android:id="@+id/tvId"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="@string/msg"
    /&gt;        
&lt;/LinearLayout&gt;
</pre>

<p>
In the <i>main.xml</i> file we have a ProgressBar and a TextView.
The ProgressBar has the default style, which is the circular style.
This is the same as if we have used the 
<i>style="?android:attr/progressBarStyle"</i> attribute.
</p>

<div class="codehead">strings.xml</div>
<pre class="code">
&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;resources&gt;
    &lt;string name="app_name"&gt;CirProgBar&lt;/string&gt;
    &lt;string name="msg"&gt;Please wait...&lt;/string&gt;
&lt;/resources&gt;
</pre>

<p>
We have two string resources in the <i>strings.xml</i> file.
</p>


<div class="codehead">MainActivity.java</div>
<pre class="code">
package com.zetcode.progbar;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.view.View;
import android.util.Log;

public class MainActivity extends Activity
{
    ProgressBar pb;
    TextView tv;
    int prg = 0;

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        pb = (ProgressBar) findViewById(R.id.pbId);
        tv = (TextView) findViewById(R.id.tvId);
 
        new Thread(myThread).start();
    }

    private Runnable myThread = new Runnable()
    { 
        @Override
        public void run() 
        {
            while (prg &lt; 100)
            {
                try
                {
                    hnd.sendMessage(hnd.obtainMessage());
                    Thread.sleep(100);
                }
                catch(InterruptedException e) 
                {  
                    Log.e("ERROR", "Thread was Interrupted");
                }
            }

            runOnUiThread(new Runnable() { 
                public void run() {
                    tv.setText("Finished");
                    pb.setVisibility(View.GONE); 
                }
            });          
        }
    
        Handler hnd = new Handler()
        {    
            @Override
            public void handleMessage(Message msg) 
            {
                prg++;
                pb.setProgress(prg);
            }
        };
    };
}
</pre>

<p>
The code is similar to the first example with a few modifications.
</p>

<pre class="explanation">
runOnUiThread(new Runnable() { 
    public void run() {
        tv.setText("Finished");
        pb.setVisibility(View.GONE); 
    }
}); 
</pre>

<p>
After the task was completed, we hide the ProgressBar using the
<code>setVisibility()</code> method. The circle itself is an endless animation, 
so after the task was finished, we need to hide the widget.
</p>


<img src="/img/java/android/progbar2.png" alt="Circular ProgressBar widget">
<div class="figure">
Figure: Circular ProgressBar widget
</div>


<p>
In this chapter of the Android development tutorial, we have mentioned
ProgressBar widget. 
</p>

<div class="center"> 
<script type="text/javascript"><!--
google_ad_client = "pub-9706709751191532";
/* horizontal */
google_ad_slot = "1734478269";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script> 
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> 
</script> 
</div>
<br> 



<div class="botNav, center">
<span class="botNavItem"><a href="/">Home</a></span> ‡ <span class="botNavItem"><a href="..">Contents</a></span> ‡ 
<span class="botNavItem"><a href="#">Top of Page</a></span>
</div>


<div class="footer">
<div class="signature">
<a href="/">ZetCode</a> last modified November 5, 2012  <span class="copyright">&copy; 2007 - 2013 Jan Bodnar</span>
</div>
</div>

</div> <!-- content -->

</div> <!-- container -->

</body>
</html>

